package showtime.framework.component.loading
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	
	import showtime.framework.core.pattern.Singleton;
	import showtime.framework.utils.StringUtility;
	import showtime.framework.manager.RevisionManager;
	
	

	/**
	 * @project Client
	 * @date 2011-7-22
	 * @author 绿豆蛙
	 * 
	 */
	public class QueueLoader extends Singleton
	{	
		protected var loadedQueue:Array = null;

		private var loadingQueue:Array = null;
		
		private var isRunning:Boolean = false;
		
		private var bmpCache:Object = null;
		
		private var xmlCache:Object = null;

		private var lastAccessURL:String = null;
		
		static public function getInstance():QueueLoader
		{
			return QueueLoader(Singleton.getInstanceOrCreate(QueueLoader));
			
		}
		public function QueueLoader()
		{
			super();
		}
		
		override protected function initialize():void
		{
			super.initialize();
			
			loadedQueue = [];
			
			loadingQueue = [];
			
			bmpCache = {};
			
			xmlCache = {};
		}
		
		/**
		 * 加载资源。
		 *  
		 * @param url
		 * 
		 */		
		public function load(url:String):void
		{
			for each (var key:String in loadingQueue)
			{
				if (key == url)
				{
					return;
				}
			}
			
			loadingQueue.push(url);
			loadedQueue.push(url);
			
			if (isRunning)
			{
				return;
			}
			else
			{
				start();
			}
		}
		
		private function start():void
		{
			lastAccessURL = loadedQueue.shift();
			
			var request:URLRequest = new URLRequest(lastAccessURL);
			switch (StringUtility.filePathToFileExt(request.url).toLocaleLowerCase())
			{
				// 加载SWF。
				case "swf":
				{
					var swfLoader:Loader = new Loader();
					
					swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoadCompleteHandler);
					swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					// Jugde is http protocol.
					if (StringUtility.isHTTP(request.url))
					{
						swfLoader.load(new URLRequest(request.url) , new LoaderContext(false, ApplicationDomain.currentDomain, SecurityDomain.currentDomain));
					}
					else
					{
						swfLoader.load(new URLRequest(request.url) , new LoaderContext(false, ApplicationDomain.currentDomain));	
					}
					
					break;
					
				}
					// 加载位图。
				case "jpg":
				case "png":
				case "gif":
				{
					var bmpLoader:Loader = new Loader();					
					bmpLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, bmpLoadCompleteHandler);
					bmpLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					if (StringUtility.isHTTP(request.url))
					{
						bmpLoader.load( new URLRequest(request.url+RevisionManager.getVersion( request.url ) ),new LoaderContext( false, ApplicationDomain.currentDomain, SecurityDomain.currentDomain ) );
					}else
					{
						bmpLoader.load( new URLRequest(request.url),new LoaderContext( false, ApplicationDomain.currentDomain ) );
					}
					break;
				}
				// 加载XML。	
				case "xml":
				{	
					var xmlLoader:URLLoader = new URLLoader();
					
					xmlLoader.addEventListener(Event.COMPLETE, xmlLoadCompleteHandler);
					xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					xmlLoader.load( new URLRequest(request.url));

					break;
				}
							
			}
			
			isRunning = true;
			
			function bmpLoadCompleteHandler(event:Event):void
			{			
				bmpCache[request.url] = Bitmap(event.target.content).bitmapData;				
				Loader(event.target.loader).contentLoaderInfo.removeEventListener(Event.COMPLETE, bmpLoadCompleteHandler);		
				Loader(event.target.loader).contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);			
				dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ONE_COMPLETE, request.url));
				
				Loader(event.target.loader).unload();
				
				if (loadedQueue.length > 0)
				{
					start();
				}
				else
				{
					dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ALL_COMPLETE));
					isRunning = false;
				}
			
			}
			
			function swfLoadCompleteHandler(event:Event):void
			{			
				Loader(event.target.loader).contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoadCompleteHandler);
				Loader(event.target.loader).contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
				
				Loader(event.target.loader).unload();
				
				dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ONE_COMPLETE, request.url));
				
				if (loadedQueue.length > 0)
				{
					start();
				}
				else
				{
					dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ALL_COMPLETE));
					isRunning = false;
				}
		

			}
			
			function xmlLoadCompleteHandler(event:Event):void
			{
				xmlCache[request.url] = XML(event.target.data);
				
				event.target.removeEventListener(Event.COMPLETE, xmlLoadCompleteHandler);
				event.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
				dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ONE_COMPLETE, request.url));
				
				if (loadedQueue.length > 0)
				{
					start();
				}
				else
				{
					dispatchEvent(new QueueProcessEvent(QueueProcessEvent.ALL_COMPLETE));
					isRunning = false;
				}

			}
			
			
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			event.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatchEvent(event);
		}
		
		
		public function getBMP(key:String):BitmapData
		{
			if (bmpCache.hasOwnProperty(key))
			{
				return bmpCache[key];
			}
			
			return null;
		}
		
		public function getXMP(key:String):XML
		{
			if (xmlCache.hasOwnProperty(key))
			{
				return XML(xmlCache[key]);
			}
			
			return null;
		}
		
		public function clear():void
		{
			
		}
	}
}